using System;
using System.Drawing;
using System.Windows.Forms;

namespace ICSharpCode.TextEditor.Gui.CompletionWindow
{
    public abstract class AbstractCompletionWindow : Control
    {
        private Form parentForm;

        private Rectangle workingScreen;

        protected Size drawingSize;

        protected TextEditorControl control;

        private static int shadowStatus;

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams result = base.CreateParams;
                AddShadowToWindow(result);
                return result;
            }
        }

        public event EventHandler Closed = null;

        protected AbstractCompletionWindow(Form parentForm, TextEditorControl control)
        {
            workingScreen = Screen.GetWorkingArea(parentForm);
            this.parentForm = parentForm;
            this.control = control;
            MinimumSize = new Size(1, 1);
            base.Size = new Size(1, 1);
            control.ActiveTextAreaControl.TextArea.Controls.Add(this);
        }

        protected virtual void SetLocation()
        {
            TextArea textArea = control.ActiveTextAreaControl.TextArea;
            TextLocation position = textArea.Caret.Position;
            int num = 0;
            int drawingXPos = textArea.TextView.GetDrawingXPos(position.Y, position.X);
            Point point = checked(new Point(textArea.TextView.DrawingPosition.X + drawingXPos, textArea.TextView.DrawingPosition.Y + textArea.Document.GetVisibleLine(position.Y) * textArea.TextView.FontHeight - textArea.TextView.TextArea.VirtualTop.Y + textArea.TextView.FontHeight + num));
            Point location = new Point(point.X, point.Y);
            Rectangle rectangle2 = (base.Bounds = new Rectangle(location, drawingSize));
        }

        public static void AddShadowToWindow(CreateParams createParams)
        {
            if (shadowStatus == 0)
            {
                shadowStatus = -1;
                if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                {
                    Version version = Environment.OSVersion.Version;
                    if (version.Major > 5 || (version.Major == 5 && version.Minor >= 1))
                    {
                        shadowStatus = 1;
                    }
                }
            }
            if (shadowStatus == 1)
            {
                createParams.ClassStyle |= 131072;
            }
        }

        protected void ShowCompletionWindow()
        {
            base.Enabled = true;
            base.Visible = true;
            control.Focus();
            if (parentForm != null)
            {
                parentForm.LocationChanged += ParentFormLocationChanged;
            }
            SetLocation();
            control.ActiveTextAreaControl.VScrollBar.ValueChanged += ParentFormLocationChanged;
            control.ActiveTextAreaControl.HScrollBar.ValueChanged += ParentFormLocationChanged;
            control.ActiveTextAreaControl.TextArea.DoProcessDialogKey += ProcessTextAreaKey;
            control.ActiveTextAreaControl.Caret.PositionChanged += CaretOffsetChanged;
            control.ActiveTextAreaControl.TextArea.LostFocus += TextEditorLostFocus;
            control.Resize += ParentFormLocationChanged;
            foreach (Control control in base.Controls)
            {
                control.MouseMove += ControlMouseMove;
            }
        }

        private void ParentFormLocationChanged(object sender, EventArgs e)
        {
            SetLocation();
        }

        public virtual bool ProcessKeyEvent(char ch)
        {
            return false;
        }

        protected virtual bool ProcessTextAreaKey(Keys keyData)
        {
            if (!base.Visible)
            {
                return false;
            }
            if (keyData == Keys.Escape)
            {
                Close();
                return true;
            }
            return false;
        }

        protected virtual void CaretOffsetChanged(object sender, EventArgs e)
        {
        }

        protected void TextEditorLostFocus(object sender, EventArgs e)
        {
            if (!control.ActiveTextAreaControl.TextArea.Focused && !base.ContainsFocus)
            {
                Close();
            }
        }

        public virtual void Close()
        {
            base.Visible = false;
            OnClosed(EventArgs.Empty);
        }

        protected virtual void OnClosed(EventArgs e)
        {
            parentForm.LocationChanged -= ParentFormLocationChanged;
            foreach (Control control in base.Controls)
            {
                control.MouseMove -= ControlMouseMove;
            }
            if (control.ActiveTextAreaControl.VScrollBar != null)
            {
                control.ActiveTextAreaControl.VScrollBar.ValueChanged -= ParentFormLocationChanged;
            }
            if (control.ActiveTextAreaControl.HScrollBar != null)
            {
                control.ActiveTextAreaControl.HScrollBar.ValueChanged -= ParentFormLocationChanged;
            }
            control.ActiveTextAreaControl.TextArea.LostFocus -= TextEditorLostFocus;
            control.ActiveTextAreaControl.Caret.PositionChanged -= CaretOffsetChanged;
            control.ActiveTextAreaControl.TextArea.DoProcessDialogKey -= ProcessTextAreaKey;
            control.Resize -= ParentFormLocationChanged;
            if (Closed != null)
            {
                Closed(this, e);
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            ControlMouseMove(this, e);
        }

        protected void ControlMouseMove(object sender, MouseEventArgs e)
        {
            control.ActiveTextAreaControl.TextArea.ShowHiddenCursor(forceShow: false);
        }
    }
}
